"""K8s资源提取器基础接口模块"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, List
import logging
import yaml
import json

class Extractor(ABC):
    """
    K8s资源提取器基础接口
    所有具体提取器必须实现extract方法
    """
    
    def __init__(self, logger: Optional[logging.Logger] = None):
        """
        初始化提取器
        
        Args:
            logger: 日志记录器，可选
        """
        self.logger = logger or logging.getLogger(__name__)
        # 资源类型，子类应覆盖此属性
        self.resource_type = "Unknown"
    
    @abstractmethod
    def extract(self, content: str, file_path: str = "") -> Dict[str, Any]:
        """
        从K8s资源配置中提取关键信息
        
        Args:
            content: YAML/JSON格式的资源内容
            file_path: 资源文件路径，可选，用于日志记录
            
        Returns:
            提取的结构化信息字典
        """
        pass
    
    def parse_content(self, content: Any, file_path: str = "") -> Dict[str, Any]:
        """
        解析字符串内容为字典对象
        
        Args:
            content: YAML/JSON格式的字符串或已解析的字典
            file_path: 文件路径，用于日志记录
            
        Returns:
            解析后的字典
        """
        # 如果content已经是字典类型，直接返回
        if isinstance(content, dict):
            return content
            
        try:
            # 首先尝试解析为JSON
            try:
                return json.loads(content)
            except (json.JSONDecodeError, TypeError):
                # JSON解析失败，尝试YAML
                return yaml.safe_load(content)
        except Exception as e:
            self.logger.error(f"解析内容失败: {str(e)}")
            return {}
    
    def get_resource_name(self, content: Dict[str, Any]) -> str:
        """
        获取资源名称(所有提取器通用方法)
        
        Args:
            content: 解析后的K8s资源内容
            
        Returns:
            资源名称
        """
        try:
            return content.get("metadata", {}).get("name", "unknown")
        except:
            return "unknown"
    
    def get_namespace(self, content: Dict[str, Any]) -> str:
        """
        获取命名空间(所有提取器通用方法)
        
        Args:
            content: 解析后的K8s资源内容
            
        Returns:
            命名空间
        """
        try:
            return content.get("metadata", {}).get("namespace", "default")
        except:
            return "default"
    
    def get_labels(self, content: Dict[str, Any]) -> Dict[str, str]:
        """
        获取标签(所有提取器通用方法)
        
        Args:
            content: 解析后的K8s资源内容
            
        Returns:
            标签字典
        """
        try:
            return content.get("metadata", {}).get("labels", {})
        except:
            return {}
    
    def get_annotations(self, content: Dict[str, Any]) -> Dict[str, str]:
        """
        获取注解(所有提取器通用方法)
        
        Args:
            content: 解析后的K8s资源内容
            
        Returns:
            注解字典
        """
        try:
            return content.get("metadata", {}).get("annotations", {})
        except:
            return {}
    
    def _extract_basic_info(self, resource: Dict[str, Any]) -> Dict[str, Any]:
        """
        提取基本元数据信息
        
        Args:
            resource: 解析后的资源字典
            
        Returns:
            包含基本信息的字典
        """
        metadata = resource.get("metadata", {})
        
        result = {
            "kind": self.resource_type,
            "name": metadata.get("name", ""),
            "namespace": metadata.get("namespace", "default"),
            "creation_timestamp": metadata.get("creationTimestamp", "")
        }
        
        # 提取标签和注解
        if "labels" in metadata:
            result["labels"] = metadata.get("labels", {})
            
        if "annotations" in metadata:
            result["annotations"] = metadata.get("annotations", {})
            
        return result
    
    # 为了向后兼容，添加别名
    def extract_base_info(self, resource: Dict[str, Any]) -> Dict[str, Any]:
        """提取基本信息的兼容方法，调用_extract_basic_info"""
        return self._extract_basic_info(resource)
            
    def _clean_keys(self, data: Any) -> Any:
        """
        清理和标准化键名，将驼峰命名转换为蛇形命名
        
        Args:
            data: 要处理的字典、列表或其他数据类型
            
        Returns:
            处理后的数据结构
        """
        if data is None:
            return {}
            
        if isinstance(data, list):
            return [self._clean_keys(item) if isinstance(item, (dict, list)) else item for item in data]
            
        if not isinstance(data, dict):
            return data
            
        result = {}
        for key, value in data.items():
            # 将驼峰命名转换为蛇形命名
            new_key = ''.join(['_' + c.lower() if c.isupper() else c for c in key]).lstrip('_')
            
            # 递归处理嵌套字典和列表
            if isinstance(value, dict):
                result[new_key] = self._clean_keys(value)
            elif isinstance(value, list):
                result[new_key] = [
                    self._clean_keys(item) if isinstance(item, dict) else item 
                    for item in value
                ]
            else:
                result[new_key] = value
                
        return result